home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Cafe 3
/
Visual Cafe 3.ISO
/
Vcafe
/
JFC.bin
/
AbstractFilter.java
< prev
next >
Wrap
Text File
|
1998-06-30
|
6KB
|
209 lines
/*
* @(#)AbstractFilter.java 1.1 97/11/14
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing.text.rtf;
import java.io.*;
import java.lang.*;
/**
* A generic superclass for streams which read and parse text
* consisting of runs of characters interspersed with occasional
* ``specials'' (formatting characters).
*
* <p> Most of the functionality
* of this class would be redundant except that the ByteToChar converters
* are suddently private API. Presumably this class will disappear
* when the API is made public again. (sigh) That will also let us handle
* multibyte character sets...
*
* <P> A subclass should override at least <code>write(char)</code>
* and <code>writeSpecial(int)</code>. For efficiency's sake it's a
* good idea to override <code>write(String)</code> as well. The subclass'
* initializer may also install appropriate translation and specials tables.
*
* @see OutputStream
*/
abstract class AbstractFilter extends OutputStream
{
/** A table mapping bytes to characters */
protected char translationTable[];
/** A table indicating which byte values should be interpreted as
* characters and which should be treated as formatting codes */
protected boolean specialsTable[];
/** A translation table which does ISO Latin-1 (trivial) */
static final char latin1TranslationTable[];
/** A specials table which indicates that no characters are special */
static final boolean noSpecialsTable[];
/** A specials table which indicates that all characters are special */
static final boolean allSpecialsTable[];
static {
int i;
noSpecialsTable = new boolean[256];
for (i = 0; i < 256; i++)
noSpecialsTable[i] = false;
allSpecialsTable = new boolean[256];
for (i = 0; i < 256; i++)
allSpecialsTable[i] = true;
latin1TranslationTable = new char[256];
for (i = 0; i < 256; i++)
latin1TranslationTable[i] = (char)i;
}
/**
* A convenience method that reads text from a FileInputStream
* and writes it to the receiver.
* The format in which the file
* is read is determined by the concrete subclass of
* AbstractFilter to which this method is sent.
* <p>This method does not close the receiver after reaching EOF on
* the input stream.
* The user must call <code>close()</code> to ensure that all
* data are processed.
*
* @param in An InputStream providing text.
*/
public void readFromStream(InputStream in)
throws IOException
{
byte buf[];
int count;
buf = new byte[16384];
while(true) {
count = in.read(buf);
if (count < 0)
break;
this.write(buf, 0, count);
}
}
public AbstractFilter()
{
translationTable = latin1TranslationTable;
specialsTable = noSpecialsTable;
}
/**
* Implements the abstract method of OutputStream, of which this class
* is a subclass.
*/
public void write(int b)
throws IOException
{
if (b < 0)
b += 256;
if (specialsTable[b])
writeSpecial(b);
else {
char ch = translationTable[b];
if (ch != (char)0)
write(ch);
}
}
/**
* Implements the buffer-at-a-time write method for greater
* efficiency.
*
* <p> <strong>PENDING:</strong> Does <code>write(byte[])</code>
* call <code>write(byte[], int, int)</code> or is it the other way
* around?
*/
public void write(byte[] buf, int off, int len)
throws IOException
{
StringBuffer accumulator = null;
while (len > 0) {
short b = (short)buf[off];
// stupid signed bytes
if (b < 0)
b += 256;
if (specialsTable[b]) {
if (accumulator != null) {
write(accumulator.toString());
accumulator = null;
}
writeSpecial(b);
} else {
char ch = translationTable[b];
if (ch != (char)0) {
if (accumulator == null)
accumulator = new StringBuffer();
accumulator.append(ch);
}
}
len --;
off ++;
}
if (accumulator != null)
write(accumulator.toString());
}
/**
* Hopefully, all subclasses will override this method to accept strings
* of text, but if they don't, AbstractFilter's implementation
* will spoon-feed them via <code>write(char)</code>.
*
* @param s The string of non-special characters written to the
* OutputStream.
*/
public void write(String s)
throws IOException
{
int index, length;
length = s.length();
for(index = 0; index < length; index ++) {
write(s.charAt(index));
}
}
/**
* Subclasses must provide an implementation of this method which
* accepts a single (non-special) character.
*
* @param ch The character written to the OutputStream.
*/
protected abstract void write(char ch) throws IOException;
/**
* Subclasses must provide an implementation of this method which
* accepts a single special byte. No translation is performed
* on specials.
*
* @param b The byte written to the OutputStream.
*/
protected abstract void writeSpecial(int b) throws IOException;
}